package com.oly.cms.admin.service.impl;

import java.util.List;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.oly.cms.admin.mapper.CmsArticleLiquidMapper;
import com.oly.cms.admin.mapper.CmsArticleMapper;
import com.oly.cms.admin.mapper.CmsCategoryMapper;
import com.oly.cms.admin.model.param.ArticleBenchParam;
import com.oly.cms.admin.service.ICmsArticleService;
import com.oly.cms.common.constant.CmsCacheConstant;
import com.oly.cms.common.constant.OlySystemConstant;
import com.oly.cms.common.domain.VisibleParam;
import com.oly.cms.common.domain.entity.CmsArticle;
import com.oly.cms.common.domain.entity.CmsCategory;
import com.oly.cms.common.domain.vo.ArticleVo;
import com.oly.cms.common.enums.CategoryNodeTypeEnums;
import com.oly.cms.common.event.CacheWebRefreshAllEvent;
import com.oly.cms.common.model.properties.OlyCmsConfigProperties;
import com.oly.cms.query.mapper.CategorySearchMapper;
import com.oly.cms.query.service.impl.ThemeSearchServiceImpl;
import com.grace.common.constant.UserConstants;
import com.grace.common.enums.SysConfigGroups;
import com.grace.common.exception.ServiceException;
import com.grace.redis.config.CacheTypeConstant;
import com.grace.system.service.impl.SysSearchConfigServiceImpl;

@Service
public class CmsArticleServiceImpl implements ICmsArticleService {
	@Autowired
	private ApplicationEventPublisher app;
	@Autowired
	private CmsArticleMapper articleMapper;
	@Autowired
	private CategorySearchMapper categorySearchMapper;
	@Autowired
	private CmsCategoryMapper categoryMapper;
	@Autowired
	private CmsArticleLiquidMapper cmsArticleLiquidMapper;
	@Autowired
	private SysSearchConfigServiceImpl configService;
	@Autowired
	private ThemeSearchServiceImpl themeService;

	/**
	 * 先插入文章 获取文章id 插入分类
	 * 
	 * 共享分类
	 * 共享分类时 同时添加至当前分类关联的主题
	 * @param arVo
	 * @return
	 */
	@Transactional
	@Override
	public int insertCmsArticle(ArticleVo arVo) {
		arVo.setArticleId(null);
		// 验证文章
		if (this.checkArticleUnique(arVo)) {
			// 顶置默认
			arVo.setArticleTop(OlySystemConstant.DEFAULT_POST_TOP);
			// 状态默认审核中
			if (arVo.getVisible() == null) {
				arVo.setVisible(Integer.parseInt(
						configService.selectConfigDefaultValue(OlyCmsConfigProperties.CMS_CONFIG_GROUP.defaultValue(),
								OlyCmsConfigProperties.ARTICLE_VISIBLE_DEFAULT)));
			}
			// 插入文章
			int reInsertNum = articleMapper.insertCmsArticle(arVo);
			// 更新关联
			this.syncArticleCategory(arVo.getArticleId(), ArrayUtils.addAll(arVo.getCategoryIds(), arVo.getTagIds()),
					arVo.getSyncThemeName());
			// 插入文章相关统计
			cmsArticleLiquidMapper.insertCmsArticleCount(arVo.getArticleId());
			// 更新缓存
			app.publishEvent(new CacheWebRefreshAllEvent(this, CmsCacheConstant.ARTICLE_CACHE_KEY_PREFIX+CacheTypeConstant.DEPEND_PREFIX));
			return reInsertNum;
		} else {
			throw new ServiceException("参数验证校验失败,请检查！");
		}
	}

	/**
	 * 批量删除文章
	 */
	@Transactional
	@Override
	public int deleteCmsArticleByIds(Long[] articleIds) {
		Long[] categoryIds = cmsArticleLiquidMapper.selectCategoryIdsByArticleIds(articleIds);
		cmsArticleLiquidMapper.batchDeleteArticleCategoryByArticleIds(articleIds);
		cmsArticleLiquidMapper.deleteCmsCommentByIds(articleIds);
		cmsArticleLiquidMapper.deleteCmsCommentRecordByIds(articleIds);
		cmsArticleLiquidMapper.deleteCmsCollectRecordByIds(articleIds);
		cmsArticleLiquidMapper.deleteCmsLookRecordByIds(articleIds);
		cmsArticleLiquidMapper.deleteCmsLikeRecordByIds(articleIds);
		cmsArticleLiquidMapper.deleteCmsNastyRecordByIds(articleIds);
		cmsArticleLiquidMapper.deleteCmsShareRecordByIds(articleIds);
		cmsArticleLiquidMapper.deleteCmsScoreRecordByIds(articleIds);
		cmsArticleLiquidMapper.deleteCmsArticleCountByIds(articleIds);
		articleMapper.deleteCmsArticleByIds(articleIds);
		this.updateCategoryArticleCount(categoryIds);
		for (Long articleId : articleIds) {
			app.publishEvent(new CacheWebRefreshAllEvent(this, CmsCacheConstant.ARTICLE_CACHE_KEY_PREFIX+CacheTypeConstant.ITEM_PREFIX+"("+articleId));
		}
		app.publishEvent(new CacheWebRefreshAllEvent(this, CmsCacheConstant.ARTICLE_CACHE_KEY_PREFIX+CacheTypeConstant.DEPEND_PREFIX));
		return articleIds.length;
	}

	/**
	 * 批量更新顶置
	 * 
	 * @param benchParam
	 * @return
	 */
	@Override
	public int batchArticleTop(ArticleBenchParam benchParam) {
		int re = articleMapper.benchArticleTop(benchParam);
		for (Long articleId : benchParam.getArticleIds()) {
			app.publishEvent(new CacheWebRefreshAllEvent(this, CmsCacheConstant.ARTICLE_CACHE_KEY_PREFIX+CacheTypeConstant.ITEM_PREFIX+"("+articleId));
		}
		app.publishEvent(new CacheWebRefreshAllEvent(this, CmsCacheConstant.ARTICLE_CACHE_KEY_PREFIX+CacheTypeConstant.DEPEND_PREFIX));
		return re;
	}

	/**
	 * 批量更新状态
	 * @param benchParam
	 * @return
	 */
	@Override
	public int batchArticleVisible(ArticleBenchParam benchParam) {
		int re = articleMapper.benchArticleVisible(benchParam);
		for (Long articleId : benchParam.getArticleIds()) {
			app.publishEvent(new CacheWebRefreshAllEvent(this, CmsCacheConstant.ARTICLE_CACHE_KEY_PREFIX+CacheTypeConstant.ITEM_PREFIX+"("+articleId));
		}
		app.publishEvent(new CacheWebRefreshAllEvent(this, CmsCacheConstant.ARTICLE_CACHE_KEY_PREFIX+CacheTypeConstant.DEPEND_PREFIX));
		return re;
	}

	/**
	 *
	 * @param id
	 * @return
	 */
	@Override
	public ArticleVo selectCmsArticleById(Long id) {
		return articleMapper.selectCmsArticleById(id);
	}

	@Override
	public List<CmsArticle> listCmsArticle(ArticleVo artVo) {
		return articleMapper.listCmsArticle(artVo);
	}

	@Override
	@Transactional
	public int updateCmsArticleById(ArticleVo cmsArticle) {
		// 修改文章
		if (this.checkArticleUnique(cmsArticle) && cmsArticle.getArticleId() != null) {
			int up=articleMapper.updateCmsArticleById(cmsArticle);
			// 更新关联
			this.syncArticleCategory(cmsArticle.getArticleId(),
					ArrayUtils.addAll(cmsArticle.getCategoryIds(), cmsArticle.getTagIds()),
					cmsArticle.getSyncThemeName());
			app.publishEvent(new CacheWebRefreshAllEvent(this, CmsCacheConstant.ARTICLE_CACHE_KEY_PREFIX+CacheTypeConstant.ITEM_PREFIX+"("+cmsArticle.getArticleId()));
			return up;
		} else {
			throw new ServiceException("参数验证校验失败,请检查！");
		}

	}

	/** 参数验证 */
	@Override
	public boolean checkArticleUnique(CmsArticle cmsArticle) {
		CmsArticle c = articleMapper.checkArticleUnique(cmsArticle);
		Long articleId = cmsArticle.getArticleId() == null ? -1L : cmsArticle.getArticleId();
		if (c == null || c.getArticleId().longValue() == articleId.longValue()) {
			return UserConstants.UNIQUE;
		}
		return UserConstants.NOT_UNIQUE;
	}
    
	/**
	 * 批量更新关联
	 * @param categoryIds
	 */
	private void updateCategoryArticleCount(Long[] categoryIds) {
		if (!ArrayUtils.isEmpty(categoryIds)) {
			cmsArticleLiquidMapper.updateCmsCategoryArticleCountByIds(categoryIds);
			for (Long item : categoryIds) {
				app.publishEvent(new CacheWebRefreshAllEvent(this, CmsCacheConstant.CATEGORIES_CACHE_KEY_PREFIX+CacheTypeConstant.ITEM_PREFIX+"("+item));
			}
		}
	}

	/**
	 * 主题T1 分类C 文章P1,P2
	 * 主题T2 分类C 文章P2,P3
	 * 取所有主题文章分类文章交集
	 * 
	 * @param articleId
	 * @param categoryIds
	 * @param syncThemeName
	 */
	private void syncArticleCategory(Long articleId, Long[] categoryIds, String syncThemeName) {
		// 移除所有关联
		this.deleteArticleCategory(articleId);
		String fb = configService.selectConfigDefaultValue(SysConfigGroups.CMS_CONFIG.getValue(),
				OlyCmsConfigProperties.CATEGORY_MUST_THEME);
		List<CmsCategory> categories = categorySearchMapper.listCmsCategoryByIds(categoryIds);
		if (syncThemeName == null) {
			if ("false".equals(fb)) {
				for (CmsCategory category : categories) {
					this.insertArticleCategory(category, articleId);
				}
			} else {
				throw new ServiceException("请选择发布站点后再试");
			}
		} else {
			// 获取主题列表 当前分类关联的主题
			for (CmsCategory category : categories) {
				if (cmsArticleLiquidMapper.checkThemeIncludeCategory(syncThemeName, category.getCategoryId()) == 1) {
					insertArticleCategory(category, articleId);
				}
			}
			categoryUnionArticle(themeService.selectCmsThemeByWt(syncThemeName).getSupportCategoryId(), articleId);
		}
	}

	private void insertArticleCategory(CmsCategory category, Long articleId) {
		// 获取主题列表 当前分类关联的主题
		int maxCategoryNum = Integer.parseInt(configService.selectConfigDefaultValue(
				OlyCmsConfigProperties.CMS_CONFIG_GROUP.defaultValue(), OlyCmsConfigProperties.ARTICLE_CAT_MAX_NUM));
		int maxTagNum = Integer.parseInt(configService.selectConfigDefaultValue(
				OlyCmsConfigProperties.CMS_CONFIG_GROUP.defaultValue(), OlyCmsConfigProperties.ARTICLE_TAG_MAX_NUM));
		int addCategoryNum = 0, addTagNum = 0;
		// 关联分类类型
		if (category.getNodeType() == CategoryNodeTypeEnums.CLASSIFY.ordinal()
				|| category.getNodeType() == CategoryNodeTypeEnums.CLASSIFY_TRUCK.ordinal()) {
			if (maxCategoryNum > addCategoryNum) {
				categoryUnionArticle(category.getCategoryId(), articleId);
				addCategoryNum++;
			}
		}
		// 关联标签类型
		else if (category.getNodeType() == CategoryNodeTypeEnums.TAG.ordinal()
				|| category.getNodeType() == CategoryNodeTypeEnums.TAG_TRUCK.ordinal()) {
			if (maxTagNum > addTagNum) {
				categoryUnionArticle(category.getCategoryId(), articleId);
				addTagNum++;
			}
		} else {
			categoryUnionArticle(category.getCategoryId(), articleId);
		}
	}

	/**
	 * 依据文章清空文章关联的分类标签
	 * 
	 * @param articleId
	 */
	private void deleteArticleCategory(Long articleId) {
		VisibleParam vParam = new VisibleParam();
		vParam.setId(articleId);
		List<CmsCategory> categories = categorySearchMapper.listArticleCategoryByArticleId(vParam);
		for (CmsCategory category : categories) {
			if (category.getNodeType() == CategoryNodeTypeEnums.CLASSIFY.ordinal()
					|| category.getNodeType() == CategoryNodeTypeEnums.CLASSIFY.ordinal()
					|| category.getNodeType() == CategoryNodeTypeEnums.TAG_TRUCK.ordinal()
					|| category.getNodeType() == CategoryNodeTypeEnums.TAG.ordinal()
					|| category.getNodeType() == CategoryNodeTypeEnums.THEME_TRUCK.ordinal()) {
				cmsArticleLiquidMapper.deleteArticleCategory(articleId, category.getCategoryId());
			}
		}
	}

	private void categoryUnionArticle(Long categoryId, Long articleId) {
		cmsArticleLiquidMapper.insertArticleCategory(articleId, categoryId);
		app.publishEvent(new CacheWebRefreshAllEvent(this, CmsCacheConstant.CATEGORIES_CACHE_KEY_PREFIX+CacheTypeConstant.ITEM_PREFIX+"("+categoryId));
		categoryMapper.updateCmsCategoryCountById(categoryId);
	}

	/**
	 * 移除关联通过主题
	 * 
	 * @param articleId
	 * @param categoryId
	 * @param syncThemeNames
	 */
	@Override
	public int removeArticleCategory(Long articleId, Long[] categoryIds, String themeName) {
		// 获取主题列表 当前分类关联的主题
		for (Long categoryId : categoryIds) {
			cmsArticleLiquidMapper.deleteArticleCategory(articleId, categoryId);
			categoryMapper.updateCmsCategoryCountById(categoryId);
		}

		cmsArticleLiquidMapper.deleteArticleCategory(
				themeService.selectCmsThemeByWt(themeName).getSupportCategoryId(),
				articleId);
		return 1;
	}

	/**
	 * 添加关联 通过主题
	 * 
	 * @param articleId
	 * @param categoryId
	 * @param syncThemeNames
	 */
	@Override
	public int addArticleCategory(Long articleId, Long[] categoryIds, String themeName) {
		// 获取主题列表 当前分类关联的主题
		for (Long categoryId : categoryIds) {
			if (cmsArticleLiquidMapper.checkThemeIncludeCategory(themeName, categoryId) == 1) {
				cmsArticleLiquidMapper.insertArticleCategory(categoryId, articleId);
				categoryMapper.updateCmsCategoryCountById(categoryId);
			}
		}

		cmsArticleLiquidMapper.deleteArticleCategory(
				themeService.selectCmsThemeByWt(themeName).getSupportCategoryId(),
				articleId);
		return 1;
	}

	/**
	 * 移除关联通过分类ID
	 * 
	 * @param articleId
	 * @param categoryId
	 * @param syncThemeNames
	 */
	@Override
	public int removeArticleCategory(Long articleId, Long categoryId, List<String> syncThemeNames) {
		// 获取主题列表 当前分类关联的主题
		for (String themeName : syncThemeNames) {
			cmsArticleLiquidMapper.deleteArticleCategory(articleId, categoryId);
			cmsArticleLiquidMapper
					.deleteArticleCategory(themeService.selectCmsThemeByWt(themeName).getSupportCategoryId(),
							articleId);
		}
		categoryMapper.updateCmsCategoryCountById(categoryId);

		return 1;
	}

	/**
	 * 添加关联通过分类ID
	 * 
	 * @param articleId
	 * @param categoryId
	 * @param syncThemeNames
	 */
	@Override
	public int addArticleCategory(Long articleId, Long categoryId, List<String> syncThemeNames) {
		// 获取主题列表 当前分类关联的主题
		for (String themeName : syncThemeNames) {
			if (cmsArticleLiquidMapper.checkThemeIncludeCategory(themeName, categoryId) == 1) {
				cmsArticleLiquidMapper.insertArticleCategory(categoryId, articleId);
			}
		}
		return categoryMapper.updateCmsCategoryCountById(categoryId);
	}

	@Override
	public Long[] selectCategoryIdsByArticleIds(Long[] articleIds) {
		return cmsArticleLiquidMapper.selectCategoryIdsByArticleIds(articleIds);
	}

	@Override
	@Transactional
	public int batchArticleCategory(ArticleVo articleVo) {
		// updateArticleCategory(articleVo.getArticleId(), articleVo.getCategoryIds());
		return updateArticleUpdateBy(articleVo.getArticleId(), articleVo.getUpdateBy());
	}

	@Override
	public int updateArticleUpdateBy(Long articleId, String updateBy) {
		return articleMapper.updateArticleUpdateBy(articleId, updateBy);
	}

}
